package com.ethink.warehouse.manager;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ethink.framework.common.constant.CommonRespCode;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.id.generator.IdGenerator;
import com.ethink.warehouse.api.enums.MateInventoryAdjustLogOrderStatusEnum;
import com.ethink.warehouse.api.info.MatePurchaseCodeInfo;
import com.ethink.warehouse.common.entity.*;
import com.ethink.warehouse.common.mapper.*;
import com.ethink.warehouse.common.model.MateInventoryAutoAdjustItemModel;
import com.ethink.warehouse.common.model.MateInventoryAutoAdjustModel;
import com.ethink.warehouse.service.SubWarehouseService;
import com.ethink.warehouse.service.impl.MateInventoryAdjustLogServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 库存矫正记录 Service接口实现
 *
 * @author default
 * @date 2022-11-17
 */
@Slf4j
@Service
public class MateInventoryAdjustManager {

    @Autowired
    private MateInventoryAdjustLogMapper mateInventoryAdjustLogMapper;

    @Autowired
    private MateInventoryAdjustLogDetailMapper mateInventoryAdjustLogDetailMapper;

    @Autowired
    private MateInventoryAdjustLogServiceImpl.MateInventoryAdjustLogDetailService mateInventoryAdjustLogDetailService;

    @Autowired
    private SubWarehouseService subWarehouseService;

    @Autowired
    private MatePurchaseCodeMapper matePurchaseCodeMapper;

    @Autowired
    private MateInventoryMapper mateInventoryMapper;

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private MateInventoryManager mateInventoryManager;
    @Autowired
    private SubWarehouseMapper subWarehouseMapper;

    @Transactional(rollbackFor = Exception.class)
    public void autoAdjust(MateInventoryAutoAdjustModel autoAdjustModel) {
        SubWarehouse subWarehouse = subWarehouseMapper.selectOne(
                new LambdaQueryWrapper<SubWarehouse>()
                        .eq(SubWarehouse::getSubWarehouseCode, autoAdjustModel.getSubWarehouseCode())
                        .eq(SubWarehouse::getIsDeleted, false));
        MateInventoryAdjustLog adjustLog = new MateInventoryAdjustLog();
        List<MateInventoryAdjustLogDetail> detailList = new ArrayList<>();
        adjustLog.setOrderNo(idGenerator.jz());
        adjustLog.setSubWarehouseCode(autoAdjustModel.getSubWarehouseCode());
        adjustLog.setSubWarehouseName(subWarehouse.getSubWarehouseName());
        adjustLog.setOrderStatus(MateInventoryAdjustLogOrderStatusEnum.S3.getIntValue());
        adjustLog.setAdjustType(autoAdjustModel.getAdjustType());
        adjustLog.setAdjustReason(autoAdjustModel.getAdjustReason());
        adjustLog.setCreateUserCode("system");
        adjustLog.setCreateUserName("system");
        adjustLog.setAuditUserCode("system");
        adjustLog.setAuditUserName("system");
        int totalQuantity = 0;
        BigDecimal totalCost = new BigDecimal(0);
        for (MateInventoryAutoAdjustItemModel item : autoAdjustModel.getItems()) {
            MateInventoryDetailOrder beforeMateInventory = item.getBeforeMateInventory();
            MatePurchaseCodeInfo matePurchaseCode = matePurchaseCodeMapper
                    .getMatePurchaseCodeByProduceCode(beforeMateInventory.getMateSku(),
                            item.getRealProduceCode());
            if (matePurchaseCode == null) {
                throw new BusinessException(CommonRespCode.SYSTEM_ERR, "商品编码" +
                        beforeMateInventory.getMateSku() + ",生产批次" +
                        item.getRealProduceCode() + ",无法匹配到采购批次，不能自动更正批次");
            }
            MateInventoryAdjustLogDetail adjustLogDetail = new MateInventoryAdjustLogDetail();
            adjustLogDetail.setOrderNo(adjustLog.getOrderNo());
            adjustLogDetail.setBeforeMateInventoryId(beforeMateInventory.getMateInventoryId());
//                adjustLogDetail.setAfterMateInventoryId();
//                adjustLogDetail.setAdjustPurchaseCode();
            adjustLogDetail.setAdjustQty(beforeMateInventory.getActualInQty());
            adjustLogDetail.setMatchPurchaseCode(matePurchaseCode.getPurchaseCode());
            adjustLogDetail.setAdjustProduceCode(item.getRealProduceCode());
            adjustLogDetail.setAdjustCostPrice(beforeMateInventory.getCostPrice());
            adjustLogDetail.setAdjustPurchaseOrderNo(matePurchaseCode.getPurchaseOrderNo());
            adjustLogDetail.setAdjustPurchaseDetailOrderNo(matePurchaseCode.getPurchaseDetailOrderNo());
            adjustLogDetail.setAdjustCountryOfOrigin(matePurchaseCode.getCountryOfOrigin());
            adjustLogDetail.setAdjustProductDate(matePurchaseCode.getProductDate());
            adjustLogDetail.setAdjustExpireDate(matePurchaseCode.getExpireDate());
            adjustLogDetail.setAdjustRkTime(matePurchaseCode.getCreateTime());
            adjustLogDetail.setSourceOrderNo(item.getSourceOrderNo());
            adjustLogDetail.setSourceDetailOrderNo(item.getSourceDetailOrderNo());
            detailList.add(adjustLogDetail);
            totalQuantity += adjustLogDetail.getAdjustQty();
            totalCost = totalCost.add(adjustLogDetail.getAdjustCostPrice().multiply(new BigDecimal(adjustLogDetail.getAdjustQty())));
        }
        adjustLog.setTotalQuantity(totalQuantity);
        adjustLog.setTotalCost(totalCost);
        mateInventoryAdjustLogMapper.insert(adjustLog);
        mateInventoryAdjustLogDetailService.saveBatch(detailList);
        // 出库,入库
        Map<Long, MateInventory> map = mateInventoryManager.adjustMateInventory(adjustLog, detailList);
        map.forEach((detailId, afterMateInventory) -> {
            mateInventoryAdjustLogDetailMapper.update(null,
                    new LambdaUpdateWrapper<MateInventoryAdjustLogDetail>()
                            .eq(MateInventoryAdjustLogDetail::getId, detailId)
                            .set(MateInventoryAdjustLogDetail::getAfterMateInventoryId, afterMateInventory.getId())
                            .set(MateInventoryAdjustLogDetail::getAdjustPurchaseCode, afterMateInventory.getPurchaseCode())
            );
        });
    }
}
